#include "QuoteMgr.h"

#include "SSCompanyReportManager.h"
#include "CompanyReport.h"
#include <string.h>
#include <core/Utility.h>

bool QuoteMgr::UpdateBondInfoByREPORT(CBondCompanyRep* pRep, REPORT* pReport, bool bVers, int bidask /*= 0*/)
{
	//pReport从网络消息中解析而来
	Q_ASSERT(pReport);
	if (!pReport || !pRep)
		return false;

	REPORT report;
	memset(&report, 0, sizeof(report));

	if (strcmp(pReport->m_price_status, "0") == 0) //无效报价
	{
		if (bidask == 1)
		{
			if (strlen(pReport->m_bidinfo.m_sPrice) == 0)
				FIELDCOPY(pReport->m_bidinfo.m_sPrice, "Bid");
		}
		if (bidask == -1)
		{
			if (strlen(pReport->m_askinfo.m_sPrice) == 0)
				FIELDCOPY(pReport->m_askinfo.m_sPrice, "Ofr");
		}
	}
	else //有效报价
	{
		if (strcmp(pReport->m_bp_status, "0") != 0) //非0时，清空本地缓存数据。（0表示发布）
		{
			if (bidask == 1)
			{
				memset(pReport->m_bidinfo.m_quotetype, 0, sizeof(pReport->m_bidinfo.m_quotetype));
				memset(pReport->m_bidinfo.m_flag_bargain, 0, sizeof(pReport->m_bidinfo.m_flag_bargain));
				memset(pReport->m_bidinfo.m_flag_relation, 0, sizeof(pReport->m_bidinfo.m_flag_relation));
				memset(pReport->m_bidinfo.m_flag_vip, 0, sizeof(pReport->m_bidinfo.m_flag_vip));
				memset(pReport->m_bidinfo.m_flag_bad, 0, sizeof(pReport->m_bidinfo.m_flag_bad));
				memset(pReport->m_bidinfo.m_rebate, 0, sizeof(pReport->m_bidinfo.m_rebate));
				memset(pReport->m_bidinfo.m_description, 0, sizeof(pReport->m_bidinfo.m_description));
				memset(pReport->m_bidinfo.m_clean_price, 0, sizeof(pReport->m_bidinfo.m_clean_price));
				memset(pReport->m_bidinfo.m_sPrice, 0, sizeof(pReport->m_bidinfo.m_sPrice));
				memset(pReport->m_bidinfo.m_sVolume, 0, sizeof(pReport->m_bidinfo.m_sVolume));
				memset(pReport->m_bidinfo.m_yield_price, 0, sizeof(pReport->m_bidinfo.m_yield_price));
				memset(pReport->m_bidinfo.m_interpret, 0, sizeof(pReport->m_bidinfo.m_interpret));
			}
			if (bidask == -1)
			{
				memset(pReport->m_askinfo.m_quotetype, 0, sizeof(pReport->m_askinfo.m_quotetype));
				memset(pReport->m_askinfo.m_flag_bargain, 0, sizeof(pReport->m_askinfo.m_flag_bargain));
				memset(pReport->m_askinfo.m_flag_relation, 0, sizeof(pReport->m_askinfo.m_flag_relation));
				memset(pReport->m_askinfo.m_flag_vip, 0, sizeof(pReport->m_askinfo.m_flag_vip));
				memset(pReport->m_askinfo.m_flag_bad, 0, sizeof(pReport->m_askinfo.m_flag_bad));
				memset(pReport->m_askinfo.m_rebate, 0, sizeof(pReport->m_askinfo.m_rebate));
				memset(pReport->m_askinfo.m_description, 0, sizeof(pReport->m_askinfo.m_description));
				memset(pReport->m_askinfo.m_clean_price, 0, sizeof(pReport->m_askinfo.m_clean_price));
				memset(pReport->m_askinfo.m_sPrice, 0, sizeof(pReport->m_askinfo.m_sPrice));
				memset(pReport->m_askinfo.m_sVolume, 0, sizeof(pReport->m_askinfo.m_sVolume));
				memset(pReport->m_askinfo.m_yield_price, 0, sizeof(pReport->m_askinfo.m_yield_price));
				memset(pReport->m_askinfo.m_interpret, 0, sizeof(pReport->m_askinfo.m_interpret));
			}
		}
		else
		{
			if (bidask == 1)
			{
				if (strlen(pReport->m_bidinfo.m_sPrice) == 0)
				{
					memset(pReport->m_bidinfo.m_quotetype, 0, sizeof(pReport->m_bidinfo.m_quotetype));
					FIELDCOPY(pReport->m_bidinfo.m_sPrice, "Bid");
				}
			}
			if (bidask == -1)
			{
				if (strlen(pReport->m_askinfo.m_sPrice) == 0)
				{
					memset(pReport->m_askinfo.m_quotetype, 0, sizeof(pReport->m_askinfo.m_quotetype));
					FIELDCOPY(pReport->m_askinfo.m_sPrice, "Ofr");
				}
			}
		}

	}

	//if( strlen(pReport->m_szCode) > 0 )
	//	info.SetBondCode( pReport->m_szCode );

	bool bRet = pRep->GetCompanyRepByKey(pReport->m_company_id, report);
	if (bRet && bVers && report.m_dwVersion > pReport->m_dwVersion)
	{
		//TODO: LogReportErrorInfo(report, bidask, "m_dwVersion failed", pReport);
		return false;
	}

	if (bRet)
	{
		memset(report.m_bp_status, 0, sizeof(report.m_bp_status));
		memset(report.m_price_status, 0, sizeof(report.m_price_status));

		FIELDCOPY(report.m_bp_status, pReport->m_bp_status);
		FIELDCOPY(report.m_price_status, pReport->m_price_status);
		if (bidask == 1 && (report.m_bidinfo.m_create_time <= pReport->m_bidinfo.m_create_time || report.m_bidinfo.m_time <= pReport->m_bidinfo.m_time))
		{

			memset(&report.m_bidinfo, 0, sizeof(PRICE));
			report.m_bidinfo = pReport->m_bidinfo;
			if (pReport->m_company_id[0] != 'e' || (pReport->m_company_id[0] == 'e' && pReport->m_tradePrice[0] != '\0')) {
				//交易所行情，如果成交为空，则不覆盖本地缓存
				FIELDCOPY(report.m_tradePrice, pReport->m_tradePrice);
			}
		}
		else if (bidask == -1 && (report.m_askinfo.m_create_time <= pReport->m_askinfo.m_create_time || report.m_askinfo.m_time <= pReport->m_askinfo.m_time))
		{
			memset(&report.m_askinfo, 0, sizeof(PRICE));
			report.m_askinfo = pReport->m_askinfo;
			if (pReport->m_company_id[0] != 'e' || (pReport->m_company_id[0] == 'e' && pReport->m_tradePrice[0] != '\0')) {
				//交易所行情，如果成交为空，则不覆盖本地缓存
				FIELDCOPY(report.m_tradePrice, pReport->m_tradePrice);
			}
		}
		else if (bidask == 0 && report.m_indx_info.m_modify_time <= pReport->m_indx_info.m_modify_time) {
			report.m_indx_info = pReport->m_indx_info;//参考价
		}
		else {
			//LogReportErrorInfo(report, bidask, "modifytime is old", pReport);
			return false;
		}

		report.m_create_time = max(pReport->m_time, pReport->m_create_time);
		report.m_time = max(pReport->m_time, pReport->m_create_time);
		report.m_dwVersion = pReport->m_dwVersion;

		report.m_pkg_id = pReport->m_pkg_id;
		pRep->InsertCompanyRep(report);

		//LogReportInfo(report, bidask, "Storaged", NULL);
	}
	else {
		pRep->InsertCompanyRep(*pReport);
		//LogReportInfo(report, bidask, "CompanyRep not find", NULL);
	}

	return true;
}

bool QuoteMgr::UpdateBondContainerByREPORT(CBondContainer& container, REPORT* pReport, bool bAddIfNotExist, bool bVers, REPORT* pReportLast /*= nullptr*/, int bidask /*= 0*/, int local /*= 0*/)
{
	// pReport 从消息中解析而来
	Q_ASSERT(pReport);
	if (nullptr == pReport)
		return false;

	int	id = 0;
	if (!container.GetBondInfoByKey(pReport->m_sBondKey, pReport->m_sListedMarket, nullptr, &id))
		return true;

	CBondCompanyRep* prep = BrokerRepMng->GetReportOrAdd(id);
	if (prep)
	{
		if (UpdateBondInfoByREPORT(prep, pReport, bVers, bidask))
		{
			int nVer = container.GetVersionById(pReport->m_company_id);
			if (nVer < (int)pReport->m_dwVersion) {
				container.UpdateVersionById(pReport->m_company_id, pReport->m_dwVersion, pReport->m_create_time);
			}
		}
	}

	return true;
}

